#!/bin/bash
#
#    Copyright 2016 Google, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

set -ex

# [START getting_started_useful]
BUCKET=

REGION=us-central1
ZONE=$REGION-f

GROUP=frontend-group
TEMPLATE=$GROUP-tmpl
MACHINE_TYPE=g1-small
IMAGE_FAMILY=debian-9
IMAGE_PROJECT=debian-cloud
STARTUP_SCRIPT=scripts/startup-script.sh
SCOPES="datastore,userinfo-email,logging-write,storage-full,cloud-platform"
TAGS=http-server

MIN_INSTANCES=1
MAX_INSTANCES=10
TARGET_UTILIZATION=0.6
# [END getting_started_useful]

SERVICE=frontend-web-service
WAR=getting-started-gce-1.0-SNAPSHOT.war

function print_usage() {
  echo "Usage: ${0} gce | down | gce-many | down-many"
  echo ""
  echo "This command is useful as a place to let you easily move back and forth between running or"
  echo "deploying the hello-world app.  You may add all your configuration here, so you don't need"
  echo "to change them in every version of this application."
  echo ""
  echo "gce      - mvn package; gsutil cp; gcloud compute instances create ...; - deploys to Compute Engine"
  echo "down     - tears down a single instance group"
  echo "gce-many - deploys a managed instance group"
  echo "down-many- tears down a managed instance group"
}

if [ $# = 0 ]; then
  print_usage
  exit
fi

COMMAND=$1

case $COMMAND in
  # usage flags
  --help|-help|-h)
    print_usage
    exit
    ;;

run)
  set -v
  mvn -Plocal clean jetty:run-exploded
  ;;

deploy)
  set -v
  mvn clean gcloud:deploy
  ;;

gce)
  set -v
# [START getting_started_gce_single]
  mvn clean package

  gsutil cp -r target/${WAR} config/base gs://${BUCKET}/gce/

  gcloud compute firewall-rules create allow-http-hello-world \
    --allow tcp:80 \
    --source-ranges 0.0.0.0/0 \
    --target-tags ${TAGS} \
    --description "Allow port 80 access to instances tagged with ${TAGS}"

  gcloud compute instances create my-app-instance \
    --machine-type=${MACHINE_TYPE} \
    --scopes=${SCOPES} \
    --metadata-from-file startup-script=${STARTUP_SCRIPT} \
    --zone=${ZONE} \
    --tags=${TAGS} \
    --image-family=${IMAGE_FAMILY} \
    --image-project=${IMAGE_PROJECT} \
    --metadata BUCKET=${BUCKET}
# [END getting_started_gce_single]
  ;;

down)
  set -v
  gcloud compute instances delete my-app-instance --zone=${ZONE} --quiet
  gcloud compute firewall-rules delete allow-http-hello-world --quiet
  ;;

gce-many)
  set -v +e
#
# Instance group setup
#
  mvn clean package

# First we have to create an instance template.
# This template will be used by the instance group
# to create new instances.

# [START getting_started_create_template]
  gcloud compute instance-templates create ${TEMPLATE} \
    --image-family=${IMAGE_FAMILY} \
    --image-project=${IMAGE_PROJECT} \
    --machine-type=${MACHINE_TYPE} \
    --scopes=${SCOPES} \
    --metadata-from-file startup-script=${STARTUP_SCRIPT} \
    --tags ${TAGS} \
    --metadata BUCKET=${BUCKET}
# [END getting_started_create_template]

# Add a firewall rule so that we can connect directly to
# the compute instances in the group.
  gcloud compute firewall-rules create allow-http-hello-world \
    --allow tcp:80 \
    --source-ranges 0.0.0.0/0 \
    --target-tags ${TAGS} \
    --description "Allow port 80 access to instances tagged with ${TAGS}"

# Create the managed instance group.

# [START getting_started_create_group]
  gcloud compute instance-groups managed \
    create ${GROUP} \
    --base-instance-name ${GROUP} \
    --size ${MIN_INSTANCES} \
    --template ${TEMPLATE} \
    --zone ${ZONE}
# [END getting_started_create_group]

#
# Load Balancer Setup
#

# A complete HTTP load balancer is structured as follows:
#
# 1) A global forwarding rule directs incoming requests to a target HTTP proxy.
# 2) The target HTTP proxy checks each request against a URL map to determine the
#    appropriate backend service for the request.
# 3) The backend service directs each request to an appropriate backend based on
#    serving capacity, zone, and instance health of its attached backends. The
#    health of each backend instance is verified using either a health check.
#
# We'll create these resources in reverse order:
# service, health check, backend service, url map, proxy.

# Create a health check
# The load balancer will use this check to keep track of which instances to send traffic to.
# Note that health checks will not cause the load balancer to shutdown any instances.

# [START getting_started_create_health_check]
  gcloud compute http-health-checks create ah-health-check \
    --request-path /_ah/health \
    --port 80
# [END getting_started_create_health_check]

# Create a backend service, associate it with the health check and instance group.
# The backend service serves as a target for load balancing.

# [START getting_started_create_backend_service]
  gcloud compute backend-services create $SERVICE \
    --http-health-checks ah-health-check --global
# [END getting_started_create_backend_service]

# [START getting_started_add_backend_service]
  gcloud compute backend-services add-backend $SERVICE \
    --instance-group $GROUP \
    --instance-group-zone $ZONE \
    --global
# [END getting_started_add_backend_service]

# Create a URL map and web Proxy. The URL map will send all requests to the
# backend service defined above.

# [START getting_started_create_url_map]
  gcloud compute url-maps create $SERVICE-map \
    --default-service $SERVICE
# [END getting_started_create_url_map]

# [START getting_started_create_http_proxy]
  gcloud compute target-http-proxies create $SERVICE-proxy \
    --url-map $SERVICE-map
# [END getting_started_create_http_proxy]

# Create a global forwarding rule to send all traffic to our proxy

# [START getting_started_create_forwarding_rule]
  gcloud compute forwarding-rules create $SERVICE-http-rule \
    --global \
    --target-http-proxy $SERVICE-proxy \
    --ports 80
# [END getting_started_create_forwarding_rule]

#
# Autoscaler configuration
#
# [START getting_started_set_autoscaling]
  gcloud compute instance-groups managed set-autoscaling \
    $GROUP \
    --max-num-replicas $MAX_INSTANCES \
    --target-load-balancing-utilization $TARGET_UTILIZATION \
    --zone $ZONE
# [END getting_started_set_autoscaling]

  ;;

down-many)
  set -v +e
# [START getting_started_stop_gce]
  gcloud compute instance-groups managed stop-autoscaling $GROUP --zone $ZONE --quiet
  gcloud compute forwarding-rules delete $SERVICE-http-rule --global --quiet
  gcloud compute target-http-proxies delete $SERVICE-proxy --quiet
  gcloud compute url-maps delete $SERVICE-map --quiet
  gcloud compute backend-services delete $SERVICE --global --quiet
  gcloud compute http-health-checks delete ah-health-check --quiet
  gcloud compute instance-groups managed delete $GROUP --zone $ZONE --quiet
  gcloud compute firewall-rules delete allow-http-hello-world --quiet
  gcloud compute instance-templates delete $TEMPLATE --quiet
# [END getting_started_stop_gce]
  ;;
esac
set +v
